package com.wlk.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wlk.mapper.DepartmentMapper;
import com.wlk.mapper.ProjectMapper;
import com.wlk.pojo.Department;
import com.wlk.pojo.dto.CodeAnalysisDTO;
import com.wlk.pojo.dto.DepUserDTO;
import com.wlk.pojo.dto.DepartmentDTO;
import com.wlk.pojo.dto.ProSelectDepDTO;
import com.wlk.service.DepartmentService;
import com.wlk.utils.CodeAnalysisUtil;
import com.wlk.utils.Result;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.lang.reflect.Field;
import java.util.List;
import java.util.logging.Logger;

@Service
public class DepartmentServiceImpl extends ServiceImpl<DepartmentMapper, Department> implements DepartmentService {

    @Resource
    private DepartmentMapper departmentMapper;
    @Resource
    private ProjectMapper projectMapper;
    /**
     * @description: 新增部门操作
     * @author:
     * @date: 2024/6/12 下午5:27
     * @param:
     * @return:
     **/
    @Override
    @Transactional
    public Result addDepartment(DepartmentDTO departmentDTO) {

        String depName = departmentDTO.getDepName();
        Integer depHeaderId = departmentDTO.getDepHeaderId();
        String depCode = departmentDTO.getDepCode();
       // 对传递的对象属性进行校验，有为null或''的，返回错误信息
        if ((depName == null || depName.equals(""))||
                (depHeaderId == null || depHeaderId.equals(""))||
                (depCode == null || depCode.equals(""))) {
            return Result.fail("部门信息不能为空！");
        }

        //对数据传输对象进行解析，通过编码规则对传递的部门代码进行解析
        CodeAnalysisDTO codeAnalysisDTO = CodeAnalysisUtil.analyzeCode(depCode, 2);
        //根据解析的返回对象进行判断是否符合编码规则
        if (codeAnalysisDTO.equals(new CodeAnalysisDTO(-1,-1))) {
            //不符合编码规则
            return Result.fail("代码不符合编码规则，请检查后重新输入,可能已到最大创建级次！");
        }
        //解析通过之后，查询项目表看父级节点部门是否绑定了项目，如果有则不能添加
        String parentDepCode = String.valueOf(codeAnalysisDTO.getParent());
        if (projectMapper.getProByDepCode(parentDepCode)>0) {
            return Result.fail("父级部门已绑定项目，不能添加子部门！");
        }
        Integer level = codeAnalysisDTO.getLevel();
        //查看其父级部门是否存在
        Integer isExistParent = departmentMapper.isExist(parentDepCode);
        if (level>1&&isExistParent<0) {
            return Result.fail("不符合编码规则，不存在上一级部门");
        }
        // 验证部门代码是否重复或存在
        Integer exist = departmentMapper.isExist(departmentDTO.getDepCode());
        if (exist>0) {
            return Result.fail("部门代码已存在，请检查后重新输入！");
        }

        //3.通过以上验证后将数据插入数据库，并将父节点的isDetailed字段改为0
        //如果level为1，则说明是根节点，直接插入数据库
       Department department = new Department();
       department.setDepCode(depCode);
       department.setDepHeaderId(depHeaderId);
       department.setDepName(depName);
       department.setDepLevel(level);
       Result result;
       // level大于1,则需要将父节点的isDetailed字段改为0
        // level大于1,则需要将父节点的isDetailed字段改为0
        if (level > 1) {
            departmentMapper.updateDepIsDetailedByParentCodeSetZero(parentDepCode);
        }
        departmentMapper.addDep(department);
        return Result.ok("添加部门成功！");
    }

    @Override
    @Transactional
    public Result deleteDepartment(String depCode) {
        //1.通过通过部门代码查看是否被绑定了项目
        Integer isExistInPro = projectMapper.getProByDepCode(depCode);
        if (isExistInPro>0) {
            return Result.fail("部门已绑定项目，不能删除！");
        }
        //验证目标部门是否存在
        Integer exist = departmentMapper.isExist(depCode);
        if (exist<0) {
            return Result.fail("目标部门不存在");
        }
        //2.查看部门是否明细，若为父节点，返回不能删除信息
        Integer isDetailedByDepCode = departmentMapper.getIsDetailedByDepCode(depCode);
        if (isDetailedByDepCode.equals(0)) {
            return Result.fail("存在子节点，不能删除！");
        }
        //3.通过以上校验后开始删除准备，查看是否有同父子节点，如果有，直接删除
        CodeAnalysisDTO codeAnalysisDTO = CodeAnalysisUtil.analyzeCode(depCode, 2);
        // 不存在父节点（自己就是根节点），直接删除
        if(codeAnalysisDTO.getParent().equals(-1)){
                departmentMapper.delDepByDepCode(depCode);
                return Result.ok("删除部门成功！");
        }
        String parentDepCode = String.valueOf(codeAnalysisDTO.getParent());
        String likeParentDepCode = parentDepCode.trim() + "__";
        Integer depLevel = codeAnalysisDTO.getLevel();
        Integer isExistSameLevelNodeByParentCode = departmentMapper.checkSameLevelNodeByParentCode(likeParentDepCode, depLevel);
        if (isExistSameLevelNodeByParentCode>1) {
            departmentMapper.delDepByDepCode(depCode);
            return Result.ok("删除部门成功！");
        }else{
            departmentMapper.updateDepIsDetailedByParentCodeSetOne(parentDepCode);
            departmentMapper.delDepByDepCode(depCode);
            return Result.ok("删除部门成功！");
        }
    }

    @Override
    @Transactional
    public Result updateDepartment(Department department) {
        // 将新旧DepCode获取并进行解析
        String newDepCode = department.getDepCode();
        String oldDepCode = departmentMapper.getDepCodeByDepId(department.getDepId());
        CodeAnalysisDTO newCodeAnalysisDTO = CodeAnalysisUtil.analyzeCode(newDepCode, 2);
        CodeAnalysisDTO oldCodeAnalysisDTO = CodeAnalysisUtil.analyzeCode(oldDepCode, 2);
        Object parentFromNewCode = newCodeAnalysisDTO.getParent();
        Object parentFromOldCode = oldCodeAnalysisDTO.getParent();
        Integer levelFromNewCode = newCodeAnalysisDTO.getLevel();
        Integer levelFromOldCode = oldCodeAnalysisDTO.getLevel();
        //1.通过部门代码查询是否绑定了项目
        Integer isExistInPro = projectMapper.getProByDepCode(oldDepCode);
        if (projectMapper.getProByDepCode(oldDepCode)>0) {
            return Result.fail("部门已绑定项目，不能修改！");
        }
        //2.校验要传递的部门代码是否合法（还在原来的父级之下，编码规则的合法性校验）
        CodeAnalysisDTO codeAnalysisDTO = CodeAnalysisUtil.analyzeCode(department.getDepCode(), 2);
        String parentDepCode = String.valueOf(codeAnalysisDTO.getParent());
        if (codeAnalysisDTO.equals(new CodeAnalysisDTO(-1,-1))) {
            //不符合编码规则
            return Result.fail("代码不符合编码规则，请检查后重新输入！");
        }
        if (!parentFromNewCode.equals(parentFromOldCode) || !levelFromNewCode.equals(levelFromOldCode)) {
            return Result.fail("部门代码修改必须同父同级！");
        }
        //2.查询要修改的部门代码是否已经存在
        Integer exist = departmentMapper.isExist(newDepCode);
        if (exist>0) {
            return Result.fail("部门代码已存在，请检查后重新输入！");
        }
        // 验证属性是否合法
        if (department.getDepName()==null || department.getDepName().equals("")) {
            return Result.fail("部门名称不能为空！");
        }
        if (department.getDepHeaderId()==null || department.getDepHeaderId().equals("")) {
            return Result.fail("部门负责人不能为空！");
        }
        //3.查询是否存在子节点，存在则不允许修改
        Integer isDetailedByDepCode = departmentMapper.getIsDetailedByDepCode(oldDepCode);
        if (isDetailedByDepCode.equals(0)) {
            return Result.fail("存在子节点，不能修改！");
        }
        //4.经过校验后允许修改
       departmentMapper.updateDep(department);
        return Result.ok("修改部门成功！");
    }

    @Override
    public Result getDepListForPro() {
        List<ProSelectDepDTO> listForPro = departmentMapper.getDepListForPro();
        return Result.ok(listForPro);
    }

    /**
     * @description: 获取部门列表
     * @author:
     * @date: 2024/6/14 下午5:31
     * @param:
     * @return:
     **/
    @Override
    public Result getDepUserList() {
        List<DepUserDTO> depUserDTOS = departmentMapper.getDepUserList();
        return Result.ok(depUserDTOS);
    }
}
